﻿using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Frame
{
    #region 注册表操作类
    /// <summary>
    /// 注册表操作类,默认基础类为HKEY_LCOAL_MACHINE
    /// </summary>
    public static class RegistryHelper
    {
        //根据程序是32位还是64位来自动决定
        private static RegistryKey _baseKey = Registry.LocalMachine;
        //如需要指定是操作32位还是64位注册表，使用下面的语句
        //private static RegistryKey _baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);

        /// <summary>
        /// 注册表基础项
        /// </summary>
        public static RegistryKey BaseKey { get { return _baseKey; } set { _baseKey = value; } }


        /// <summary>
        /// 操作后返回的信息，为空表示操作正确，异常则为异常信息。
        /// </summary>
        public static string State { get; set; } = string.Empty;

        #region 注册表目录项是否存在
        /// <summary>
        /// 读取注册表目录项，位于BaseKey下
        /// </summary>
        /// <param name="FullPath">(除HKLM等基础类型外)全路径</param>
        /// <param name="Folder">目录项名称</param>
        /// <returns>bool值，true成功，false失败，失败则查看State</returns>
        public static bool IsRegistryFolderExist(string FullPath, string Folder)
        {
            try
            {
                RegistryKey OpenKey = BaseKey.OpenSubKey(FullPath);

                string[] subkeyNames = OpenKey.GetValueNames();
                BaseKey.Close();

                return subkeyNames.ToList().Exists(u => u == Folder);

            }
            catch (Exception ex)
            {
                State = ex.Message;
                return false;
            }

        }
        #endregion

        #region 创建注册表目录项
        /// <summary>
        /// 创建注册表目录项,位于BaseKey下
        /// </summary>
        /// <param name="Folder">目录项名称</param>
        /// <param name="FullPath">(除HKLM等基础类型外)全路径</param>
        /// <returns>bool值，true成功，false失败，失败则查看State</returns>
        public static bool CreatRegistryFolder(string FullPath, string Folder)
        {
            try
            {
                RegistryKey OpenKey = BaseKey.CreateSubKey(FullPath + "\\" + Folder);
                return true;
            }
            catch (Exception ex)
            {
                State = ex.Message;
                return false;
            }

        }
        #endregion

        #region 删除注册表目录项
        /// <summary>
        /// 删除注册表目录项，位于BaseKey下
        /// </summary>
        /// <param name="FullPath">(除HKLM等基础类型外)全路径</param>
        /// <param name="Folder">目录项名称</param>
        /// <returns>bool值，true成功，false失败，失败则查看State</returns>
        public static bool DelRegistryFolder(string FullPath, string Folder)
        {
            try
            {
                BaseKey.DeleteSubKey(FullPath + "\\" + Folder, true); //该方法无返回值，直接调用即可
                BaseKey.Close();
                return true;
            }
            catch (Exception ex)
            {
                State = ex.Message;
                return false;
            }
        }

        #endregion

        #region 注册表目录下键是否存在
        /// <summary>
        /// 读取注册表目录下键是否存在,位于BaseKey下
        /// </summary>
        /// <param name="FullPath">(除HKLM等基础类型外)全路径</param>
        /// <param name="subKeyName">子键名称</param>
        /// <returns>bool值，true成功，false失败，失败则查看State</returns>
        public static bool IsRegistryKeyExit(string FullPath, string subKeyName)
        {
            try
            {
                string[] subkeyNames = BaseKey.OpenSubKey(FullPath).GetValueNames();
                BaseKey.Close();

                return subkeyNames.ToList().Exists(u => u == subKeyName);
            }
            catch (Exception ex)
            {
                State = ex.Message;
                return false;
            }
        }
        #endregion

        #region 创建、修改注册表子键
        /// <summary>
        ///  创建、修改注册表子键,位于BaseKey下
        /// </summary>
        /// <param name="FullPath">(除HKLM等基础类型外)全路径</param>
        /// <param name="Key">键的名称</param>
        /// <param name="Value">键对应的值</param>
        /// <returns>bool值，true成功，false失败，失败则查看State</returns>
        public static bool CreateOrSetRegistryKey(string FullPath, string Key, object Value)
        {
            try
            {
                RegistryKey OpenKey = Registry.LocalMachine.CreateSubKey(FullPath); //该项必须已存在
                // 注意：SetValue()还有第三个参数，主要是用于设置键值的类型，如：字符串，二进制，Dword等等~~默认是字符串。如：
                // OpenKey.SetValue("test", "0", RegistryValueKind.DWord); //二进制信息
                OpenKey.SetValue(Key, Value);

                OpenKey.Close();
                return true;
            }
            catch (Exception ex)
            {
                State = ex.Message;
                return false;
            }

        }
        #endregion

        #region 读取注册表子键的值
        /// <summary>
        /// 读取注册表子键的值，位于BaseKey下
        /// </summary>
        /// <param name="FullPath">(除HKLM等基础类型外)全路径</param>
        /// <param name="Key">键的名称</param>
        /// <returns>键对应的值，如出错，则查看State</returns>
        public static object GetRegistryKeyValue(string FullPath, string Key)
        {
            try
            {
                RegistryKey OpenKey = Registry.LocalMachine.OpenSubKey(FullPath);
                object keyValue = OpenKey.GetValue(Key);
                OpenKey.Close();

                return keyValue;
            }
            catch (Exception ex)
            {
                State = ex.Message;
                return ex.Message;
            }


        }
        #endregion

        #region 删除注册表子键
        /// <summary>
        /// 删除注册表子键，位于BaseKey下
        /// </summary>
        /// <param name="FullPath">(除HKLM等基础类型外)全路径</param>
        /// <param name="Key">键的名称</param>
        /// <returns>bool值，true成功，false失败，失败则查看Status</returns>
        public static bool DelRegistryKey(string FullPath, string Key)
        {
            try
            {
                RegistryKey OpenKey = Registry.LocalMachine.OpenSubKey(FullPath, true);
                OpenKey.DeleteValue(Key);
                OpenKey.Close();
                return true;
            }
            catch (Exception ex)
            {
                State = ex.Message;
                return false;
            }
        }
        #endregion

    }
    #endregion

}
